/****************************************************************
 * Fulguro
 * Copyright (C) 2004 Christophe Clienti
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 ***************************************************************/
/*********************** 1D Struct ***********************/


typedef struct {
  FLGR_Type type;
  int spp;
  int center_coord_x;
  FLGR_Vector *center_data_val;
  FLGR_Vector *center_nhb_val;
  int nhb_size_x;
  //int **list_coord_x;
  //void **list_data_val;
  //void **list_nhb_val;
  //int *size;
}FLGR_NhbBox1D;

%extend FLGR_NhbBox1D {
  FLGR_NhbBox1D(FLGR_Data1D *data) {
    return flgr1d_create_neighbor_box(data);
  }

  ~FLGR_NhbBox1D() {
    flgr1d_destroy_neighbor_box($self);
  }

  SwigObject size(int k) {
    if(k>=$self->spp) return SwigObjectEmpty;

    if(k<0) return SwigObjectEmpty;

    return SwigInt_FromCInt( $self->size[k] );
  }

  SwigObject __getitem__(int k) {
    int i; 
    SwigObject array;
    SwigObject array_x;
    SwigObject array_data;
    SwigObject array_nhb;
    int *coord_x;
    void *data_val;
    void *nhb_val;
 
    if(k<0) return SwigObjectEmpty;
    if(k>=$self->spp) return SwigObjectEmpty;
    
    array = SwigCreateArray(3);

    array_x = SwigCreateArray($self->size[k]);
    array_data = SwigCreateArray($self->size[k]);
    array_nhb = SwigCreateArray($self->size[k]);

    SwigSetArrayVal( array, 0, array_x );
    SwigSetArrayVal( array, 1, array_data );
    SwigSetArrayVal( array, 2, array_nhb );

    coord_x = $self->list_coord_x[k];
    data_val = $self->list_data_val[k];
    nhb_val = $self->list_nhb_val[k];

    for(i=0 ; i<$self->size[k] ; i++) {
      SwigSetArrayVal(array_x, i, SwigInt_FromCInt(coord_x[i]));

      switch($self->type) {
      case FLGR_BIT:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgBIT*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgBIT*) nhb_val)[i] ) ); 
	break;

      case FLGR_UINT8:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgUINT8*) data_val)[i] ) );
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgUINT8*) nhb_val)[i] ) ); 
	break;

      case FLGR_UINT16:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgUINT16*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgUINT16*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_UINT32:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgUINT32*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgUINT32*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_INT8:
	SwigSetArrayVal(array_data,i, SwigInt_FromCInt( ((fgINT8*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgINT8*) nhb_val)[i] ) ); 
	break;

      case FLGR_INT16:
	SwigSetArrayVal(array_data,i, SwigInt_FromCInt( ((fgINT16*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgINT16*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_INT32:
	SwigSetArrayVal(array_data,i, SwigInt_FromCInt( ((fgINT32*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgINT32*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_FLOAT32:
	SwigSetArrayVal(array_data,i, SwigFloat_FromCDouble( ((fgFLOAT32*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgFLOAT32*) nhb_val)[i] ) ); 
	break;

      case FLGR_FLOAT64:
	SwigSetArrayVal(array_data,i, SwigFloat_FromCDouble( ((fgFLOAT64*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgFLOAT64*) nhb_val)[i] ) ); 
	break;

      default:
	return array;
      }

    }

    return array;

  }

};



/* /\*********************** 2D Struct ***********************\/ */


 /*! 
   * Neighborhood Box 2D
   */
  typedef struct {
    FLGR_Type type;
    int spp;
    int center_coord_y;
    int center_coord_x;
    FLGR_Vector *center_data_val;
    FLGR_Vector *center_nhb_val;
    int nhb_size_y;
    int nhb_size_x;
    //int **list_coord_y;
    //int **list_coord_x;
    //void **list_data_val;
    //void **list_nhb_val;
    //int *size;
  }FLGR_NhbBox2D;



%extend FLGR_NhbBox2D {
  FLGR_NhbBox2D(FLGR_Data2D *data) {
    return flgr2d_create_neighbor_box(data);
  }

  ~FLGR_NhbBox2D() {
    flgr2d_destroy_neighbor_box($self);
  }

  SwigObject size(int k) {
    if(k>=$self->spp) return SwigObjectEmpty;

    if(k<0) return SwigObjectEmpty;

    return SwigInt_FromCInt( $self->size[k] );
  }

  SwigObject __getitem__(int k) {
    int i; 
    SwigObject array;
    SwigObject array_x;
    SwigObject array_y;
    SwigObject array_data;
    SwigObject array_nhb;
    int *coord_x;
    int *coord_y;
    void *data_val;
    void *nhb_val;
 
    if(k<0) return SwigObjectEmpty;
    if(k>=$self->spp) return SwigObjectEmpty;
    
    array = SwigCreateArray(4);

    array_x = SwigCreateArray($self->size[k]);
    array_y = SwigCreateArray($self->size[k]);
    array_data = SwigCreateArray($self->size[k]);
    array_nhb = SwigCreateArray($self->size[k]);

    SwigSetArrayVal( array, 0, array_x );
    SwigSetArrayVal( array, 1, array_y );
    SwigSetArrayVal( array, 2, array_data );
    SwigSetArrayVal( array, 3, array_nhb );

    coord_x = $self->list_coord_x[k];
    coord_y = $self->list_coord_x[k];
    data_val = $self->list_data_val[k];
    nhb_val = $self->list_nhb_val[k];

    for(i=0 ; i<$self->size[k] ; i++) {
      SwigSetArrayVal(array_x, i, SwigInt_FromCInt(coord_x[i]));
      SwigSetArrayVal(array_y, i, SwigInt_FromCInt(coord_y[i]));

      switch($self->type) {
      case FLGR_BIT:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgBIT*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgBIT*) nhb_val)[i] ) ); 
	break;

      case FLGR_UINT8:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgUINT8*) data_val)[i] ) );
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgUINT8*) nhb_val)[i] ) ); 
	break;

      case FLGR_UINT16:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgUINT16*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgUINT16*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_UINT32:
	SwigSetArrayVal(array_data,i, SwigInt_FromCUInt( ((fgUINT32*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCUInt( ((fgUINT32*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_INT8:
	SwigSetArrayVal(array_data,i, SwigInt_FromCInt( ((fgINT8*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgINT8*) nhb_val)[i] ) ); 
	break;

      case FLGR_INT16:
	SwigSetArrayVal(array_data,i, SwigInt_FromCInt( ((fgINT16*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgINT16*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_INT32:
	SwigSetArrayVal(array_data,i, SwigInt_FromCInt( ((fgINT32*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgINT32*) nhb_val)[i] ) ); 
	break;
 
      case FLGR_FLOAT32:
	SwigSetArrayVal(array_data,i, SwigFloat_FromCDouble( ((fgFLOAT32*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgFLOAT32*) nhb_val)[i] ) ); 
	break;

      case FLGR_FLOAT64:
	SwigSetArrayVal(array_data,i, SwigFloat_FromCDouble( ((fgFLOAT64*) data_val)[i] ) ); 
	SwigSetArrayVal(array_nhb,i, SwigInt_FromCInt( ((fgFLOAT64*) nhb_val)[i] ) ); 
	break;

      default:
	return array;
      }

    }

    return array;

  }

};





%feature("autodoc","""
[out] FLGR_NhbBox1D box
[in] FLGR_Data1D source
[in] FLGR_Data1D nhb definition
[in] Integer position (x)
[return] FLGR_Ret\n
Retrieve all neighbors of a pixel in 1D Data as defined in \"nhb\"
The return value correspond to constant FLGR_RET_OK,...
""") flgr1d_get_neighborhood;
FLGR_Ret flgr1d_get_neighborhood(FLGR_NhbBox1D *extr, FLGR_Data1D *img, FLGR_Data1D *nhb, int pos);

%feature("autodoc","""
[out] FLGR_NhbBox1D box
[in] FLGR_Data1D source
[in] FLGR_Data1D nhb definition
[in] Integer position (x)
[return] FLGR_Ret\n
Retrieve all neighbors of a pixel in 1D Data as defined in \"nhb\"
Border are manage as the signal was symetrized
The return value correspond to constant FLGR_RET_OK,...
""") flgr1d_get_neighborhood_unfolded;
extern FLGR_Ret flgr1d_get_neighborhood_unfolded(FLGR_NhbBox1D *extr, FLGR_Data1D *img, FLGR_Data1D *nhb, int pos);








%feature("autodoc","""
[out] FLGR_NhbBox2D box
[in] FLGR_Data2D source
[in] FLGR_Data2D nhb definition
[in] Integer column (x)
[in] Integer row (y)
[return] FLGR_Ret\n
Retrieve all neighbors of a pixel in 2D Data as defined in \"nhb\"
The return value correspond to constant FLGR_RET_OK,...
""") flgr2d_get_neighborhood;
FLGR_Ret flgr2d_get_neighborhood(FLGR_NhbBox2D *extr, FLGR_Data2D *img, FLGR_Data2D *nhb, int x, int y);

%feature("autodoc","""
[out] FLGR_NhbBox2D box
[in] FLGR_Data2D source
[in] FLGR_Data2D nhb definition
[in] Integer position
[return] FLGR_Ret\n
Retrieve all neighbors of a pixel in 2D Data as defined in \"nhb\"
Border are manage as the image was unfolded
The return value correspond to constant FLGR_RET_OK,...
""") flgr2d_get_neighborhood_unfolded;
extern FLGR_Ret flgr2d_get_neighborhood_unfolded(FLGR_NhbBox2D *extr, FLGR_Data2D *img, FLGR_Data2D *nhb, int x, int y);
